"""
JSON report loader and validator.
JSON报告加载与校验器
"""

import json
import hashlib
from pathlib import Path
from typing import Dict, List, Optional
from datetime import datetime


class ReportLoader:
    """Load and validate benchmark JSON reports.
    加载并校验基准测试JSON报告
    """
    
    def __init__(self, results_dir: str = "results"):
        # 初始化，设置结果目录路径与报告缓存
        self.results_dir = Path(results_dir)
        self.reports = {}
        
    def load_all(self) -> Dict[str, Dict]:
        """
        Load all JSON reports from results directory.
        加载目录下所有JSON报告
        
        Returns:
            Dict mapping report_id to report data
            返回报告ID到报告数据的映射字典
        """
        if not self.results_dir.exists():
            return {}
        
        for json_file in self.results_dir.glob("*.json"):
            try:
                report_id = json_file.stem  # 文件名（不含后缀）作为报告ID
                report_data = self.load_report(json_file)
                if report_data:
                    self.reports[report_id] = report_data
            except Exception as e:
                print(f"Warning: Failed to load {json_file}: {e}")
        
        return self.reports
    
    def load_report(self, filepath: Path) -> Optional[Dict]:
        """
        Load and validate a single JSON report.
        加载并校验单个JSON报告
        
        Args:
            filepath: Path to JSON file
            JSON文件的路径
            
        Returns:
            Report data dict or None if invalid
            报告数据（dict）或无效时返回None
        """
        with open(filepath, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # Basic validation
        # 基本校验
        if not self._validate_report(data):
            return None
        
        # Add metadata
        # 添加元信息
        data['_meta'] = {
            'filepath': str(filepath),
            'loaded_at': datetime.now().isoformat(),
            'file_hash': self._compute_hash(filepath)
        }
        
        return data
    
    def _validate_report(self, data: Dict) -> bool:
        """
        Validate report structure.
        校验报告结构
        
        Args:
            data: Report data dict
            报告数据字典
            
        Returns:
            True if valid
            校验通过返回True
        """
        # Check required top-level fields
        # 检查顶层字段是否齐全
        required_fields = ['env', 'run', 'models']
        if not all(field in data for field in required_fields):
            return False
        
        # Check models data
        # 检查models字段类型和内容
        if not isinstance(data['models'], dict) or len(data['models']) == 0:
            return False
        
        # Check each model has required metrics
        # 检查每个模型含有必需的指标
        required_metrics = ['qps', 'lat_avg_ms', 'p50_ms', 'p99_ms']
        for model_name, model_data in data['models'].items():
            if not all(metric in model_data for metric in required_metrics):
                return False
        
        return True
    
    def _compute_hash(self, filepath: Path) -> str:
        """Compute SHA256 hash of file.
        计算文件的SHA256哈希
        """
        sha256_hash = hashlib.sha256()
        with open(filepath, "rb") as f:
            for byte_block in iter(lambda: f.read(4096), b""):
                sha256_hash.update(byte_block)
        return sha256_hash.hexdigest()[:16]  # 返回前16位字符串

    def get_report_list(self) -> List[Dict]:
        """
        Get list of loaded reports with metadata.
        获取所有已加载报告的摘要信息列表
        
        Returns:
            List of dicts with id, name, timestamp
            列表元素为包含id、name、timestamp等的字典
        """
        result = []
        for report_id, report in self.reports.items():
            result.append({
                'id': report_id,
                'timestamp': report.get('run', {}).get('timestamp', 'N/A'),
                'num_models': len(report.get('models', {}))  # 模型数量
            })
        return result
    
    def get_all_models(self) -> List[str]:
        """
        Get list of all unique model names across all reports.
        获取所有报告中的唯一模型名称列表
        
        Returns:
            Sorted list of unique model names
            排序后的唯一模型名称列表
        """
        models_set = set()
        
        # 遍历所有报告，收集模型名称
        for report_id, report in self.reports.items():
            models = report.get('models', {})
            if isinstance(models, dict):
                models_set.update(models.keys())
        
        # 转为列表并排序，确保输出顺序一致
        return sorted(list(models_set))

